<!-- 用户选择窗口 -->
<template>
  <a-modal
    v-model:open="visible"
    title="成员"
    cancelText="取消"
    okText="确定"
    width="700px"
    @ok="handleOk"
  >
    <div class="main-content">
      <div class="left-main">
        <a-input
          allow-clear
          :placeholder="typeConfigItem['placeholder']"
          v-model:value="searchWords"
          class="input-class"
          @change="searchChange"
        >
          <template #prefix>
            <search-outlined style="color: rgba(0, 0, 0, 0.45)" />
          </template>
        </a-input>
        <template v-if="!!typeConfigItem['isOrganizational'] && !searchWords">
          <a-breadcrumb>
            <a-breadcrumb-item
              v-for="(item, index) in departmentInfo.show"
              class="hover:text-primary-6"
              :key="item.id"
              @click="breadcrumbClick(item)"
            >
              <span>{{ item.name }}</span>
              <template
                #overlay
                v-if="index && departmentInfo.show[index - 1]['children']"
              >
                <a-menu>
                  <a-menu-item
                    v-for="subItem in departmentInfo.show[index - 1][
                      'children'
                    ]"
                    :key="subItem.id"
                    @click="breadcrumbMenuClick(item, subItem)"
                  >
                    <span>{{ subItem.name }}</span>
                  </a-menu-item>
                </a-menu>
              </template>
            </a-breadcrumb-item>
          </a-breadcrumb>
        </template>
        <template
          v-else-if="
            departmentInfo.show &&
            departmentInfo.show[0] &&
            departmentInfo.show[0]['name']
          "
        >
          <a-breadcrumb>
            <a-breadcrumb-item class="primary-color">{{
              departmentInfo.show[0]['name']
            }}</a-breadcrumb-item>
          </a-breadcrumb>
        </template>
        <div class="ele-border-split sys-organization-list left-box">
          <div
            class="section-line"
            v-for="(item, index) in state.leftSideList"
            :key="index"
          >
            <div class="ele-elip section-left">
              <template v-if="!!typeConfigItem['isLeftCheck']">
                <a-checkbox
                  value="1"
                  name="type"
                  class="left-checkbox"
                  :disabled="list.includes(item.id)"
                  v-model:checked="item.checked"
                  @change="!list.includes(item.id) && leftSideChange(item)"
                />
                <div
                  class="item-box"
                  @click="leftSideChange(item, { checked: !item.checked })"
                >
                  <div class="circle-box">
                    <span
                      class="font-size-12"
                      v-if="!!typeConfigItem['isNameIcon']"
                      >{{ item.name.slice(-2) }}</span
                    >
                    <span
                      v-else
                      class="iconfont left-icon"
                      :class="[typeConfigItem['icon']]"
                    ></span>
                  </div>
                  <span>{{ item.name }}</span>
                </div>
              </template>
              <div class="ele-cell pointer" v-else>
                <div class="item-box">
                  <div class="circle-box">
                    <span
                      class="iconfont left-icon"
                      :class="[typeConfigItem['icon']]"
                    ></span>
                  </div>
                  <span>{{ item.name }}</span>
                </div>
              </div>
            </div>
            <div class="section-right">
              <div
                v-if="item.type === 'department'"
                class="flex align-center"
                @click="!item.checked && breadcrumbClick(item, true)"
              >
                <span
                  :class="[
                    'margin-right-5',
                    active === index ? 'active' : '',
                    item.checked ? 'cursor-no-drop' : 'cursor-pointer',
                    dragBoxClass,
                  ]"
                >
                  下级
                </span>
                <span class="iconfont icon-page-next"></span>
              </div>
              <template v-else-if="!!typeConfigItem['isRightCheck']">
                <a-checkbox
                  value="1"
                  name="type"
                  v-model:checked="item.checked"
                  @change="leftSideChange(item)"
                />
              </template>
            </div>
          </div>
        </div>
      </div>
      <div class="right-main">
        <div class="select-title">
          <span>已选：{{ state.rightSideList.length }} 个</span>
          <span
            class="ele-text-primary pointer clear iconfont icon-clean"
            @click="clear('all')"
          ></span>
        </div>
        <div class="select-box">
          <div
            class="select-line"
            v-for="(item, index) in state.rightSideList"
            :key="index"
          >
            <div class="select-detail">
              <div class="flex align-center">
                <div class="circle-box">
                  <span
                    class="font-size-12"
                    v-if="!!typeConfigItem['isNameIcon']"
                    >{{ item.name.slice(-2) }}</span
                  >
                  <span
                    v-else
                    class="iconfont left-icon"
                    :class="[typeConfigItem['icon']]"
                  ></span>
                </div>
                <span>{{ item.name }}</span>
              </div>
            </div>
            <span
              class="iconfont icon-close select-clear"
              v-if="!list.includes(item.id)"
              @click="clear('line', item, index)"
            ></span>
          </div>
        </div>
      </div>
    </div>
    <template #footer>
      <a-button
        type="button"
        class="vf-btn vf-btn-primary bg-primary-6"
        @click="confirm"
      >
        确定
      </a-button>
      <a-button type="button" @click="close" class="vf-btn vf-btn-secondary">
        {{ t('Cancel') }}
      </a-button>
    </template>
  </a-modal>
</template>

<script setup>
import { inject, ref, reactive, toRefs, onMounted } from 'vue'
import { SearchOutlined } from '@ant-design/icons-vue'
const app = inject('ServiceContainer')
const { getStore } = app.storage
const { t } = app.i18n
const props = defineProps({
  // 已选数据
  list: {
    type: Array,
    default: () => [],
  },
})
const emit = defineEmits(['update:list', 'confirm'])
const { list } = toRefs(props)
/**
 * 类型配置项
 * @param {boolean} isLeftCheck 是否显示左侧复选框
 * @param {boolean} isRightCheck 是否显示右侧复选框
 * @param {string} icon 显示icon名称
 * @param {boolean} isOrganizational 是否组织架构
 * @param {string} allName 显示总的名称
 */
const typeConfigItem = ref({
  title: '成员',
  placeholder: '搜索成员',
  isLeftCheck: true,
  isRightCheck: false,
  isOrganizational: true,
  isNameIcon: true,
  icon: 'icon-fork',
  allName: '用户',
})
const searchWords = ref('')
const departmentInfo = reactive({
  treeList: [], // 树形数据
  list: [], // 列表数据
  show: [], // 展示数据
})
const state = reactive({
  leftSideList: [
    // {
    //   type: 'employees',
    //   name: '总部4',
    //   checked: false
    // },
    // {
    //   type: 'roles',
    //   isLeftCheck: false,
    //   isRightCheck: true,
    //   icon: 'icon-yonghu',
    //   name: '总部2',
    //   checked: true
    // },
    // {
    //   type: 'groups',
    //   isLeftCheck: false,
    //   isRightCheck: true,
    //   icon: 'icon-yonghu2',
    //   name: '总部2',
    //   checked: true
    // }
  ],
  rightSideList: [],
})

const visible = ref(false)
let employeeList = [] // 员工列表
// 树结构转列表
const treeToList = (tree, childrenKey = 'children', keepChildren = false) => {
  const result = [];
  // 递归处理节点
  function traverse(node) {
    // 处理当前节点
    let item;
    if (keepChildren) {
      // 浅拷贝保留子节点
      item = { ...node };
    } else {
      // 拷贝并移除子节点字段
      const { [childrenKey]: _, ...rest } = node;
      item = rest;
    }
    
    result.push(item);
    
    // 处理子节点
    if (Array.isArray(node[childrenKey]) && node[childrenKey].length > 0) {
      node[childrenKey].forEach(child => traverse(child));
    }
  }
  // 遍历根节点
  tree.forEach(node => traverse(node));
  return result;
}
// 获取部门列表
const getDepartmentList = async () => {
  const { data } = await app.requester.send({
    url: '',
    method: 'get',
    params: {
      fetchType: 'department',
    },
  })
  departmentInfo.treeList = data
  departmentInfo.list = treeToList(data)
  await breadcrumbClick(data[0], false, true)
}
// 获取员工列表
const getEmployeeList = async () => {
  const { data } = await app.requester.send({
    url: '',
    method: 'get',
    params: {
      fetchType: 'employee',
    },
  })
  employeeList = data
}

// 根据部门id筛选员工
const filterIDEmployeeList = (id) => {
  state.leftSideList = [
    ...employeeList
      .filter((item) => item.departments.some((n) => n.id === id))
      .map((item) => ({
        ...item,
        type: 'employees',
        checked: state.rightSideList.some((n) => n.id === item.id),
      })),
    ...state.leftSideList,
  ]
}

// 打开弹窗
const open = async () => {
  searchWords.value = ''
  state.leftSideList = []
  state.rightSideList = []
  visible.value = true
  await getEmployeeList()
  await getDepartmentList()
  state.rightSideList = [...employeeList, ...departmentInfo.list]?.filter((item) => {
    return list.value.includes(item.id)
  })
  await breadcrumbClick(departmentInfo.treeList[0], false, true)
}

// 关闭弹窗
const close = () => {
  visible.value = false
}

// 点击面包屑
const breadcrumbClick = async (data, isNext = false, isInit = false) => {
  if (departmentInfo.show && departmentInfo.show.length > 1 && !isNext) {
    const index = departmentInfo.show.findIndex((n) => n.id === data.id)
    departmentInfo.show = [...departmentInfo.show.slice(0, index), data]
    state.leftSideList = []
  } else if (isNext) {
    departmentInfo.show.push(data)
  } else if (isInit) {
    departmentInfo.show = [data]
  }
  state.leftSideList = data.children.map((item) => ({
    ...item,
    type: 'department',
    checked: state.rightSideList.some((n) => n.id === item.id),
  }))
  filterIDEmployeeList(data.id)
}
// 点击面包屑的下拉菜单
const breadcrumbMenuClick = (data, subData) => {
  const index = departmentInfo.show.findIndex((n) => n.id === data.id)
  departmentInfo.show = [...departmentInfo.show.slice(0, index), subData]
  state.leftSideList = subData.children.map((item) => ({
    ...item,
    type: 'department',
    checked: false,
  }))
  filterIDEmployeeList(subData.id)
}
// 搜索事件
const searchChange = () => {
  const regex = new RegExp(searchWords.value, 'i') // 忽略大小写
  if (!searchWords.value)
    return breadcrumbClick(departmentInfo.treeList[0], false, true)
  state.leftSideList = [
    ...employeeList
      .filter((item) => regex.test(item.name))
      .map((item) => ({
        ...item,
        type: 'employees',
        checked: state.rightSideList.some((n) => n.id === item.id),
      })),
  ]
}
// 清除左侧列表记录(全部清除，记录行清除)
const clear = (type, data, index) => {
  if (type === 'all') {
    state.leftSideList.map((item) => {
      if (list.value.includes(item?.id)) return item
      if (item.checked) item.checked = false
      return item
    })
    state.rightSideList = state.rightSideList.filter((item) => list.value.includes(item?.id))
    return true
  }
  const flagIndex = state.leftSideList.findIndex((n) => n.id === data.id)
  if (flagIndex >= 0) state.leftSideList[flagIndex]['checked'] = false
  state.rightSideList.splice(index, 1)
}

// 确定事件
const confirm = () => {
  let arr = state.rightSideList.map((item) => {
    return item.id
  })
  emit('update:list', arr)
  emit('confirm', state.rightSideList)
  close()
}

// 左侧操作事件
const leftSideChange = (data, options = {}) => {
  if (Reflect.has(options, 'checked')) {
    data.checked = options.checked
    const leftIndex = state.leftSideList.findIndex((n) => n.id === data.id)
    state.leftSideList[leftIndex]['checked'] = options.checked
  }
  const index = state.rightSideList.findIndex((n) => n.id === data.id)
  if (data.checked) {
    state.rightSideList.push(data)
  } else {
    state.rightSideList.splice(index, 1)
  }
}

defineExpose({
  open,
  close,
})
</script>

<style lang="scss" scoped>
.ant-breadcrumb {
  padding: 10px 0 5px;
}

.ant-breadcrumb > .primary-color {
  @apply text-primary-6;
}

.flex {
  display: flex;
}

.main-content {
  @apply flex mt-[16px];
}

.left-main {
  @apply h-[60vh] flex-1 pt-[24px] pr-[16px];
}

.left-box {
  max-height: calc(60vh - 48px - 32px);
  overflow-y: auto;
  .left-icon {
    font-size: 20px;
  }

  .left-checkbox {
    padding-left: 10px;
    font-size: 15px;
  }

  .icon-zuzhijiagou {
    padding-right: 7px;
  }

  .section-line {
    display: flex;
    line-height: 50px;
    justify-content: space-between;
    font-size: 15px;

    .section-left {
      display: flex;
      max-width: 80%;
      // overflow-x: scroll;

      &::-webkit-scrollbar {
        height: 8px;
        border-radius: 5px;
      }
    }

    .section-right {
      padding: 0 10px;
      @apply text-primary-6;
    }

    .icon-page-next {
      font-size: 12px;
    }
  }
}

.right-main {
  @apply h-[60vh] pt-[24px] pl-[16px] flex-1;
}

.select-title {
  display: flex;
  line-height: 30px;
  padding-bottom: 25px;
  font-size: 15px;
  justify-content: space-between;

  .clear {
    padding: 0 20px;
    color: var(--grey-15);
  }
}

.select-box {
  max-height: calc(60vh - 48px - 32px);
  overflow-y: auto;

  .select-line {
    display: flex;
    width: 100%;
    padding: 10px 0;
    font-size: 15px;
    justify-content: space-between;
    align-items: center;

    .select-detail {
      display: flex;
      line-height: 25px;
      flex-direction: column;
    }

    .detail-sub {
      font-size: 13px;
      color: #9f9fa1;
    }

    .select-clear {
      padding: 0 20px;
    }
  }
}

.item-box {
  @apply flex items-center;
}

.circle-box {
  @apply flex justify-center items-center size-[32px] mx-[10px] text-xs rounded-[50%] bg-primary-6 text-white;
}

.vf-btn {
  margin-top: 0.125rem;
  display: inline-flex;
  width: 100%;
  height: 38px;
  justify-content: center;
  border-radius: 0.375rem;
  border-width: 1px;
  padding-left: 1rem;
  padding-right: 1rem;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  font-size: 1rem;
  line-height: 1.5rem;
  font-weight: 500;
  letter-spacing: 0.025em;
  --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000),
    var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
  margin-left: 0.25rem;
  margin-right: 0.25rem;
  width: auto;
  font-size: 0.875rem;
  line-height: 1.25rem;
  width: 5rem;
  align-items: center;
}

.bg-primary-6 {
  --tw-bg-opacity: 1;
  background-color: rgb(24 144 255 / var(--tw-bg-opacity, 1));
  border-color: transparent;
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}

.vf-btn-secondary {
  --tw-border-opacity: 1;
  border-color: rgb(209 213 219 / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
  --tw-text-opacity: 1;
  color: rgb(55 65 81 / var(--tw-text-opacity, 1));
}

.cursor-pointer{

  cursor: pointer;
}

.cursor-no-drop {
  cursor: no-drop;
}
</style>
